#!/usr/bin/python
# -*- coding: latin-1 -*-

"Módulo simple para obtener constancias del sitio de la AFIP"

__license__ = "MIT"
__version__ = "0.02"

import urllib2
import re
import cookielib
import sys
import os
import time
import socket

import opciones


class Constancia:
    "Permite bajar una constancia de inscripción AFIP"

    def __init__(self, id=0):

        self.user_agent = opciones.user_agent
        self.headers = {'User-Agent': self.user_agent}
        self.URL = "https://seti.afip.gob.ar" \
                   "/padron-puc-constancia-internet/ConstanciaAction.do"

        self.id = id
        self.okcookie = 0
        self.numcaptcha = 0
        self.captcha_img = ""
        self.html = ""
        self.dobleconstancia = 0

        socket.setdefaulttimeout(50)
        self.cookiejar = cookielib.LWPCookieJar()
        self.urlOpener = urllib2.build_opener(
                         urllib2.HTTPCookieProcessor(self.cookiejar))
        urllib2.install_opener(self.urlOpener)

    def bajar(self, cuit=0):

        self.comun = 0
        self.monotributo = 0
        self.dobleconstancia = 0
        self.cuit = validar_cuit(cuit)
        self.cuitlargo = self.cuit[: 2] + '-' + self.cuit[2: 10] \
                                        + '-' + self.cuit[10:]

        if self.cuit == False:
            self.tipoConstancia = "ERR"
            self.html = "CUIT INCORRECTA"
            return False

        if self.okcookie == 0 or self.numcaptcha == 0:
            self.tipoConstancia = "ERR"
            self.html = "CAPTCHA INCORRECTA"
            return False

        post_string = "cuit={0}&captchaField={1}".format(
                      self.cuit, self.numcaptcha)

        request = urllib2.Request(self.URL, post_string, self.headers)
        url = self.urlOpener.open(request)
        page = url.read()

        if (page.find("digo de error") + 1):
            self.tipoConstancia = "ERR"
            self.html = page
            return False

        if page.find("CUIT habilitada para") + 1:
            #Tenemos una doble constancia
            dobleconstancia = 1

            #Probamos si anda la constancia comun y si no anda, probamos
            #la del monotributo
            post_string1 = post_string + \
                           "&tipoCertificado=1" \
                           "&tipoConstanciaSelector=S"
            request = urllib2.Request(self.URL, post_string1, headers)
            url = self.urlOpener.open(request)
            page = url.read()

            if (page.find("digo de error") + 1):
                #Acá dió error la constancia común, probamos con la de
                #monotributo
                post_string1 = post_string + \
                               "&tipoCertificado=2" \
                               "&tipoConstanciaSelector=S"
                request = urllib2.Request(
                          self.URL, post_string1, headers)
                url = self.urlOpener.open(request)
                page = url.read()

                if (page.find("digo de error") + 1):
                    #Acá dió error la constancia monotributo también así
                    #que nos damos por vencidos.
                    self.tipoConstancia = "ERR"
                    self.constancia = page
                    return False

        if page.find("Verifique que haya ingresado los datos") + 1:
            self.okcookie = 0
            self.tipoConstancia = "ERR"
            self.html = "CAPTCHA INCORRECTA"
            return False

        if page.find("CONSTANCIA DE OPCION") + 1:
            #Tenemos una constancia monotributo
            self.monotributo = 1
            self.tipoConstancia = "MT"
        elif page.find("CONSTANCIA DE INSCRIPCION") + 1:
            #Tenemos una constancia común
            self.comun = 1
            self.tipoConstancia = "INS"
        else:
            #Tenemos algo raro, que no es una constancia que conozcamos
            self.tipoConstancia = "ERR"
            self.constancia = page
            return False
        self.html = page
        return True

    def bajar_captcha(self):
        "Acá entra si necesitamos un nuevo captcha"

        #solicitamos imagen de captcha de la AFIP
        try:
            request = urllib2.Request(
                      "https://seti.afip.gob.ar/"
                      "padron-puc-constancia-internet/"
                      "images/CaptchaCode.gif",
                      None, self.headers)
            url = self.urlOpener.open(request)
            self.captcha_img = url.read()
            return self.captcha_img
        except:
            return False

    def datos(self):
        if self.tipoConstancia == "ERR":
            return "ERROR, no tengo una constancia para obtener" \
                   "los datos."
        return get_datos_constancia(self.html)

    def bajar_IIBB_Cba(self, cuit):
        "Obtiene constancia de ingresos brutos de Cordoba"

        self.cuit = validar_cuit(cuit)
        self.cuitlargo = self.cuit[: 2] + '-' + self.cuit[2: 10] \
                                        + '-' + self.cuit[10:]

        URL_CBA = "http://deudasrentas.cba.gov.ar" \
                  "/itax/consulta_inscriptos.zul?ente=IB"
        request = urllib2.Request(URL_CBA)
        url = self.urlOpener.open(request) 
        page = url.read()

        t = re.findall(r'z.dtid=\"(.*?)\"', page)[0]
        r1 = re.findall(r'Cuit:.*?input id="(.*?)" z.type=', page)[0]

        uurl = 'http://deudasrentas.cba.gov.ar/' \
               'itax/zkau?cmd.0=onChange&cmd.1=onOK&data.0=' \
               + self.cuitlargo \
               + '&data.0=false&data.0=13&data.1=13&data.1=false' \
               '&data.1=false&data.1=false&dtid=' \
               + t + '&uuid.0=' + r1 + '&uuid.1=' + r1
        url = self.urlOpener.open(uurl)
        page = url.read()

        return page

    def get_datos_IIBB_Cba(self, constanciaIIBB):
        #datos[0]=Número de ingresos brutos 
        #datos[1] a datos[7]=Mas datos
        
        datos = {}
        
        try:
            datos = re.findall(
                    r'\[CDATA\[<span id=".*?">(.*?)</span>\]\]', \
                    constanciaIIBB)

        except:
             datos = None
        return datos


def get_datos_constancia_comun(s):
    "Parsea la constancia de inscripción común y devuelve datos útiles"

    if (s.find("digo de error") + 1):
        return {}

    try:
        #Recolectamos los impuestos en los que está inscripto
        a1 = s.find("IMPUESTO/REGIMEN REGISTRADO Y FECHA DE ALTA")
        a2 = s.find("*************", a1)

        datos = {}
        datos['Impuestos'] = s[a1 + 43: a2].replace("</TR>", r"\n")
        datos['Impuestos'] = remove_extra_spaces(
                             remove_html_tags(datos['Impuestos']))
        datos['Impuestos'] = "Impuesto/Régimen registrado y fecha de " \
                             "alta:\n" + datos['Impuestos']
        datos['Impuestos'] = datos['Impuestos'].replace(r"\n", "\n")

        s1 = s  # Copia sin modificar
        s = remove_extra_spaces(remove_html_tags(s))

        t = re.findall(r'CUIT(.*?) Fecha Contrato Social', s)[0]

        a1 = s.find("Fecha Contrato Social:")
        a2 = s.find("IMPUESTO", a1)
        datos['TipoCuit'] = "Fecha de contrato social: " + s[a1 + 29: a2]

    except:
        try:
            t = re.findall(r'CUIT(.*?) IMPUESTO', s)[0]
            datos['TipoCuit'] = "Responsable inscripto."
        except:
            print >> sys.stderr, "Error al parsear el comprobante de " \
                                 "inscripción:"
            print >> sys.stderr, s
            return initdatos()

    datos['CuitCompleto'] = t[8: 8 + 13]
    datos['RazonSocial'] = t[8 + 14:]

    a1 = s1.find("Domicilio Fiscal", 0)
    a2 = s1.find("Dependencia donde se encuentra", a1)
    datos['DomicilioFiscal'] = remove_extra_spaces(
                               remove_html_tags(s1[a1 + 47: a2]))\
                               .replace('&nbsp;', '')\
                               .strip()
    datos['DomicilioFiscal2'] = remove_extra_spaces(
                                remove_html_tags(s1[a1 + 47: a2]\
                                .replace("</FONT>", "|||</FONT>")\
                                .replace('&nbsp;', '')))\
                                .strip()

    #Actividades del contribuyente
    a1 = s.find("Actividad principal")
    a2 = s.find("Mes de cierre", a1)
    datos['Actividades'] = s[a1: a2]\
        .replace('&nbsp;', '')\
        .replace('   ', '\n')\
        .replace('principal:', 'principal:\n')\
        .replace('Actividad secundaria(s) :',
                 '\nActividad secundaria(s) :\n')\
        .replace('\n\n', '\n')\
        .replace('  ', ' ')

    #Cargamos una lista de los números de actividades
    datos['ActividadesNum'] = re.findall(r'\n +(.+?) ',
                                       datos['Actividades'])
    #Si hay solamente una actividad, borramos la actividad
    #secundaria vacía
    if len(datos['ActividadesNum']) == 1:
        datos['Actividades'] = datos['Actividades'][:datos['Actividades']\
                               .find('Actividad secundaria') - 2]
    elif len(datos['ActividadesNum']) == 0:
        datos['ActividadesNum'] = ["-"]

    return datos


def get_datos_monotributo(s):
    "Parsea la constancia de monotributo y devuelve datos útiles"
    #datos['CuitCompleto']
    #datos['RazonSocial']
    #datos['DomicilioFiscal']
    #datos['FechaInicio']
    #datos['TipoCuit']

    if (s.find("digo de error") + 1):
        return {}
    datos = {}

    a1 = s.find("CUIT:")
    a2 = s.find("SIZE=4>", a1)
    datos['CuitCompleto'] = s[a2 + 7: a2 + 20]

    a2 = s.find("SIZE=4>", a2 + 1)
    a3 = s.find("</FONT>", a2 + 1)
    datos['RazonSocial'] = s[a2 + 7: a3]

    a2 = s.find("SIZE=4>", a2 + 7)
    a3 = s.find("Fecha inicio Monotributo", a2 + 7)
    datos['DomicilioFiscal'] = remove_extra_spaces(
                               remove_html_tags(s[a2 + 7: a3]))\
                               .replace('&nbsp;', '')\
                               .strip()
    datos['DomicilioFiscal2'] = remove_extra_spaces(
                                remove_html_tags(
                                s[a2 + 7: a3]\
                                .replace("</FONT>", "|||</FONT>")\
                                .replace('&nbsp;', '')))\
                                .strip()

    #Averiguamos la fecha de inicio de monotributo
    datos['FechaInicio'] = s[a3: a3 + 37]

    #Averiguamos que categoría de monotributo es
    a2 = s.find(r"<FONT face=Arial SIZE=4>CATEGORIA</FONT>", a3 + 20)
    cat = remove_extra_spaces(remove_html_tags(
                              s[a2 + 40: a2 + 40 + 111]))
    datos['TipoCuit'] = "Es monotributo categoría" + cat
    datos['ActividadesNum'] = ["-"]

    a2 = s.find(r"Integrantes de la sociedad", a2 + 20)
    if a2 + 1:
        a3 = s.find(r"<TABLE", a2 + 20)
        soc = s[a2: a3].replace(r'</TD>', r'###ENTER###')
        soc = remove_extra_spaces(remove_html_tags(soc))
        soc = soc.replace(r'###ENTER###', "\n")
        soc = soc.replace("&nbsp;\n", "")
        datos['Sociedad'] = soc

    return datos


def validar_cuit(cuit):
    try:
        cuit = str(cuit)
        cuit = cuit.replace("-", "")  # borro las barras
        cuit = cuit.replace(" ", "")  # borro los espacios
        cuit = cuit.replace(".", "")  # borro los puntos

        if len(cuit) != 11:
            return False

        base = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]

        # calculo el dígito verificador:
        aux = 0
        for i in xrange(10):
            aux += int(cuit[i]) * base[i]

        aux = 11 - (aux - (int(aux / 11) * 11))

        if aux == 11:
            aux = 0
        if aux == 10:
            aux = 9

        if aux == int(cuit[10]):
            return cuit
        else:
            return False
    except:
        return False


def remove_html_tags(data):
    p = re.compile(r'<.*?>')
    return p.sub('', data)


def remove_extra_spaces(data):
    p = re.compile(r'\s+')
    return p.sub(' ', data)


def get_datos_constancia(page):
    if page.find("CONSTANCIA DE OPCION") + 1:
        #Tenemos una constancia monotributo
        return get_datos_monotributo(page)

    elif page.find("CONSTANCIA DE INSCRIPCION") + 1:
        #Tenemos una constancia común
        return get_datos_constancia_comun(page)
    else:
        #Tenemos algo raro, que no es una constancia que conozcamos
        return ""


if __name__ == '__main__':
    from StringIO import StringIO
    import Image
    print 1
    c = Constancia()
    print 2
    while not c.bajar(30500010912):
        print 3
        if c.html == "CAPTCHA INCORRECTA":
            c.bajar_captcha()
            captcha = StringIO(c.captcha_img)
            img = Image.open(captcha)
            img.show()
            c.numcaptcha = raw_input("Captcha: ")
            c.okcookie = True
    print get_datos_constancia(c.html)['RazonSocial']
    constanciaiibb = c.bajar_IIBB_Cba()
    print c.get_datos_IIBB_Cba(constanciaiibb)['NroIIBB']
